/*********************************** (C) COPYRIGHT ******************************
 * address: https://gitee.com/liuniansihuo/multitasks-os
 *
 * Change Logs:
 * Date			Author      	Notes
 * 2019-06-16	LiuHuo			first version
 *
 * Modify Note:  for support typeof() arm gcc must set zhe  "--gnu"
*******************************************************************************/


#include "list.h"



//struct list_head my_list=LIST_HEAD_INTT(my_list);

void list_init(struct list_head *head)
{
	head->next = head;
	head->prev = head;
}

// add a node to head
void list_add(struct list_head *new, struct list_head *head)
{
	if(list_is_exit(new,head))
		return;
	new->next = head->next;
	new->prev = head;
	head->next->prev= new;
	head->next = new;
}
// add a node to tail
void list_add_tail(struct list_head *new, struct list_head *head)
{
#if 0
	if(list_is_exit(new,head))
		return;
	new->next = head;
	new->prev=head->prev;
	head->prev->next = new;
	head->prev = new;
#else
	list_add(new, head->prev);
#endif

}
//delet zhe entry node
void list_del(struct list_head *entry)
{
	entry->prev->next = entry->next;
	entry->next->prev = entry->prev;
}

//delet zhe entry node and init zhe node
void list_del_init(struct list_head *entry)
{
	list_del(entry);
	entry->next = entry;
	entry->prev = entry;
}

//new replace old
void list_replace(struct list_head *old, struct list_head *new)
{
	if(list_is_exit(new,old))
		return;
	new->next = old->next;
	new->prev = old->prev;
	old->prev->next = new;
	old->next->prev = new;
}

//new replace old and zhe old init
void list_replace_init(struct list_head *old, struct list_head *new)
{
	list_replace(old, new);
	old->next = old;
	old->prev = old;
}

//move zhe list node to zhe head, but zhe list must in head
void list_move(struct list_head *list, struct list_head *head)
{
	list_del(list);
	list_add(list, head);
}
//move zhe list node to zhe tail, but zhe list must in head
void list_move_tail(struct list_head *list, struct list_head *head)
{
	list_del(list);
	list_add_tail(list, head);
}
//list to head's head
void list_splice(struct list_head *list, struct list_head *head)
{
	if(list_is_exit(list,head))
		return;
	list->prev->next = head->next;
	head->next->prev = list->prev;
	head->next = list->next;
	list->next->prev = head;
}
//list to head's tail
void list_splice_tail(struct list_head *list, struct list_head *head)
{
#if 0
	if(list_is_exit(list,head))
		return;
	list->next->prev = head->prev;
	head->prev->next = list->next;
	head->prev = list->prev;
	list->prev->next = head;
#else
	list_splice(list, head->prev);
#endif
}
//list to head's head and init zhe list
void list_splice_init(struct list_head *list, struct list_head *head)
{
	list_splice(list, head);
	list->next = list;
	list->prev=list;
}
//list to head's tail,and init zhe list
void list_splice_tail_init(struct list_head *list, struct list_head *head)
{
	list_splice_tail(list, head);
	list->next = list;
	list->prev=list;
}
#if 0//no test check
// zhe head's node of before entry to list, others keep in head;zhe entry must in head;if entry == head ,zhe return,
void list_cut_position(struct list_head *list, struct list_head *head,struct list_head *entry)
{
	if(head == entry)
		return;

	list->next = head->next;
	list->prev = entry;


	head->next = entry->next;
	entry->next->prev = head;

	entry->next = list;
	list->next->prev = list;

}
#endif
//zhe list is zhe last node?? yes,return 1;no return 0
int list_is_last(const struct list_head *list,const struct list_head *head)
{
	return ((head->prev == list)&&(list->next==head));
}

int list_empty(const struct list_head *head)
{
	return ((head->next==head) && (head->prev == head));
}
// is only one??
int list_is_singular(const struct list_head *head)
{
	return ((head->next->next== head) && (head->prev->prev==head));
}

int list_is_exit(const struct list_head *list,const struct list_head *head)
{
	struct list_head *pos;
	list_for_each(pos,head)
	{
		if(pos == list)
			return 1;
	}
	return 0;
}
